package cn.virens.library.widget.adapter;

import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by loioi on 2017/2/24.
 */
public abstract class AbstractAdapter<T> extends RecyclerView.Adapter<AbstractAdapter.RecyclerViewHolder> {
    /**
     * 数据集
     */
    protected final List<T> mDataSet = new ArrayList<>();
    /**
     * Item Layout的资源id
     */
    private int mItemLayoutId;

    public AbstractAdapter() {
    }

    public AbstractAdapter(int layoutID) {
        this.mItemLayoutId = layoutID;
    }

    public AbstractAdapter(int layoutID, List<T> list) {
        this(layoutID);
        this.mDataSet.addAll(list);
    }


    /**
     * 移除一条数据
     *
     * @param position
     */
    public void remove(int position) {
        if (position >= getItemCount()) return;
        mDataSet.remove(position);

        notifyItemRemoved(position);
        notifyItemRangeChanged(position, getItemCount() - position);
    }

    /**
     * 添加一条数据
     *
     * @param item
     */
    public void add(T item) {
        if (item == null) return;
        mDataSet.add(item);
        notifyItemInserted(getItemCount() - 1);
    }

    /**
     * 指定位置添加一条数据
     *
     * @param position
     * @param item
     */
    public void add(int position, T item) {
        if (item == null || position >= getItemCount()) return;
        mDataSet.add(position, item);
        notifyItemRangeChanged(position, getItemCount() - position);
    }

    /**
     * 添加多条数据
     *
     * @param items
     */
    public void addAll(List<T> items) {
        if (items == null || items.isEmpty()) return;
        int position = getItemCount();
        mDataSet.addAll(items);
        notifyItemRangeInserted(position, getItemCount() - position);
    }

    /**
     * 指定位置开始添加多条数据
     *
     * @param position
     * @param items
     */
    public void addAll(int position, List<T> items) {
        if (items == null || items.isEmpty() || position >= getItemCount()) return;
        mDataSet.addAll(position, items);
        notifyItemRangeChanged(position, getItemCount() - position);
    }

    /**
     * 替换指定位置的数据
     *
     * @param position
     * @param item
     */
    public void set(int position, T item) {
        if (item == null || position >= getItemCount()) return;
        T tmp = mDataSet.set(position, item);
        notifyItemChanged(position);
    }

    /**
     * 替换全部数据
     *
     * @param items
     */
    public void setAll(List<T> items) {
        if (items == null) return;
        mDataSet.clear();
        mDataSet.addAll(items);
        notifyDataSetChanged();
    }

    public List<T> getDataSet() {
        return new ArrayList<>(mDataSet);
    }

    /**
     * 清空数据
     */
    public void clear() {
        mDataSet.clear();
        notifyDataSetChanged();
    }

    /**
     * 获取指定位置的数据项
     *
     * @param position
     * @return
     */
    public T getItem(int position) {
        return mDataSet.get(position);
    }

    /**
     * 获取数据总条数
     *
     * @return
     */
    @Override
    public int getItemCount() {
        return mDataSet.size();
    }

    /**
     * 根据Type返回布局资源
     *
     * @param type
     * @return
     */
    protected int getItemLayout(int type) {
        return mItemLayoutId;
    }

    /**
     * 解析布局资源
     *
     * @param viewGroup
     * @param viewType
     * @return
     */
    protected View inflateItemView(ViewGroup viewGroup, int viewType) {
        return LayoutInflater.from(viewGroup.getContext()).inflate(getItemLayout(viewType), viewGroup, false);
    }

    /**
     * 创建视图持有者
     *
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerViewHolder holder = new RecyclerViewHolder(inflateItemView(parent, viewType));

        this.configRecyclerViewHolder(holder);

        return holder;
    }

    @Override
    public void onBindViewHolder(AbstractAdapter.RecyclerViewHolder holder, int position) {
        holder.position = position;

        this.onBindData(holder, getItem(position)); // 绑定数据
    }

    /**
     * 配置 视图持有者
     *
     * @param holder RecyclerViewHolder
     */
    protected abstract void configRecyclerViewHolder(final RecyclerViewHolder holder);

    /**
     * 绑定数据到Item View上
     *
     * @param viewHolder
     * @param item       数据项
     */
    protected abstract void onBindData(RecyclerViewHolder viewHolder, T item);


    public class RecyclerViewHolder extends RecyclerView.ViewHolder {
        public int position;
        /**
         * 缓存子视图,key为view id, 值为View。
         */
        private SparseArray<View> mCahceViews = new SparseArray<>();

        public RecyclerViewHolder(View itemView) {
            super(itemView);
        }

        /**
         * 查找itemView 下的控件
         *
         * @param viewId
         * @param <V>
         * @return
         */
        public <V extends View> V findViewById(int viewId) {
            View target = mCahceViews.get(viewId);
            if (target == null) {
                target = itemView.findViewById(viewId);
                mCahceViews.put(viewId, target);
            }
            return (V) target;
        }
    }

}
